package com.okaixz.common.client.utils;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolUtils {
    private static ThreadPoolUtils instances;
    private static int THREADCOUNT = 5;// cpu核数*2+1
    private ThreadPoolProxy netPoolProxy;
    private ThreadPoolProxy nativePoolProxy;
    private ThreadPoolProxy downLoadPoolProxy;
    private ThreadPoolProxy uploadPoolProxy;

    private static Object netObject = new Object();
    private static Object nativeObject = new Object();
    private static Object downLoadObject = new Object();
    private static Object uploadObject = new Object();

    private ThreadPoolUtils() {

    }

    public static ThreadPoolUtils getInstances() {
        if (instances == null) {
            instances = new ThreadPoolUtils();
        }
        return instances;
    }

    /**
     * 读取网络
     *
     * @return
     */
    public synchronized ThreadPoolProxy createNetPool() {
        synchronized (netObject) {

            if (netPoolProxy == null) {
                netPoolProxy = new ThreadPoolProxy(THREADCOUNT, THREADCOUNT);
            }

            return netPoolProxy;
        }
    }

    /**
     * 读取本地
     *
     * @return
     */
    public synchronized ThreadPoolProxy createNativePool() {

        synchronized (nativeObject) {
            if (nativePoolProxy == null) {
                nativePoolProxy = new ThreadPoolProxy(THREADCOUNT, THREADCOUNT);
            }

            return nativePoolProxy;
        }
    }

    public synchronized ThreadPoolProxy createDownLoadPool() {
        synchronized (downLoadObject) {
            if (downLoadPoolProxy == null) {
                downLoadPoolProxy = new ThreadPoolProxy(THREADCOUNT,
                        THREADCOUNT);
            }

            return downLoadPoolProxy;
        }
    }


    public synchronized ThreadPoolProxy createUploadPool() {
        synchronized (uploadObject) {
            if (uploadPoolProxy == null) {
                uploadPoolProxy = new ThreadPoolProxy(1,
                        THREADCOUNT);
            }

            return uploadPoolProxy;
        }
    }

    /**
     * 线程池代理
     *
     * @author Administrator
     */
    public class ThreadPoolProxy {
        private ThreadPoolExecutor executor;
        private int corePoolSize;
        private int maximumPoolSize;

        public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
        }

        // 执行
        public void execute(Runnable runnable) {
            if (executor == null) {
                executor = new ThreadPoolExecutor(corePoolSize,
                        maximumPoolSize, 2 * 60 * 1000, TimeUnit.MILLISECONDS,
                        new LinkedBlockingDeque<Runnable>(20));
                executor.execute(runnable);
            } else {
                try {
                    //RejectedExecutionException 如果运行的线程少于corePoolSize，则Executor始终首选添加新的线程，而不进行排队。
                    //如果运行的线程等于或多于corePoolSize，则Executor始终首选将请求加入队列，而不添加新的线程。
                    //如果无法将请求加入队列，则创建新的线程，除非创建此线程超出maximumPoolSize，在这种情况下，任务将被拒绝（抛出RejectedExecutionException）。
                    executor.execute(runnable);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public void cancle(Runnable runnable) {
            if (executor != null && !executor.isShutdown()
                    && !executor.isTerminated()) {

                boolean remove = executor.remove(runnable);
            }
        }
    }

}
